﻿using System;
using System.IO;
using System.Text;
using Isaac.Joy.Identity.Module;
using Isaac.Joy.Ormapping.Contract;
using Isaac.Joy.Serialize;
using UIShell.OSGi;

namespace Isaac.Joy.Identity.Repository.SqlClient
{
    class Database
    {
        private static IDatabase _instence;
        public static IDatabase Instence
        {
            get
            {
                if (_instence != null) return _instence;

                var factory = BundleRuntime.Instance.GetFirstOrDefaultService<IDatabaseProviderFactory>();
                _instence = factory.CreateDefault();

                var path = Path.Combine(Activator.BundleContext.Bundle.Location, "Install.xml");
                var config = XmlSerializable.LoadFromXml<InstallConfig>(path);
                if (config == null) return _instence;
                if (config.NeedCreateTable == "1")
                {
                    CreateTable();
                    config.NeedCreateTable = "0";
                }

                if (config.NeedCreatePermission == "1")
                {
                    CreatePermission();
                    config.NeedCreatePermission = "0";
                }
                else if (config.NeedCreatePermission == "2")
                {
                    ResetPermission();
                    config.NeedCreatePermission = "0";
                }

                XmlSerializable.SaveXml(config, path);
                return _instence;
            }
        }

        private static void CreateTable()
        {
            var sbSql = new StringBuilder();
            sbSql.AppendLine("IF EXISTS (");
            sbSql.AppendLine("SELECT * FROM sysobjects");
            sbSql.AppendLine("WHERE id = OBJECT_ID('[Isaac_Joy_Identity_User]') AND OBJECTPROPERTY(id, 'IsUserTable') = 1");
            sbSql.AppendLine(") DROP TABLE Isaac_Joy_Identity_User");

            sbSql.AppendLine("CREATE TABLE Isaac_Joy_Identity_User");
            sbSql.AppendLine("(");
            sbSql.AppendLine("Id int IDENTITY(1,1) NOT NULL,");
            sbSql.AppendLine("Account nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Password char(32) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Email nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("NickName nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Birthday datetime NOT NULL DEFAULT(GETDATE()),");
            sbSql.AppendLine("Mobile nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Tel nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("QQ nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Address nvarchar(500) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Gender int NOT NULL DEFAULT(0),");
            sbSql.AppendLine("CreateTime datetime NOT NULL DEFAULT(GETDATE()),");
            sbSql.AppendLine("UpdateTime datetime NOT NULL DEFAULT(GETDATE()),");
            sbSql.AppendLine("IsDelete int NOT NULL DEFAULT(0),");
            sbSql.AppendLine("Roleid int NOT NULL DEFAULT(0)");
            sbSql.AppendLine(")");

            sbSql.AppendLine("ALTER TABLE Isaac_Joy_Identity_User");
            sbSql.AppendLine("WITH NOCHECK ADD CONSTRAINT Pk_Isaac_Joy_Identity_User PRIMARY KEY NONCLUSTERED ( [Id] )");

            sbSql.AppendLine("IF EXISTS (");
            sbSql.AppendLine("SELECT * FROM sysobjects");
            sbSql.AppendLine("WHERE id = OBJECT_ID('[Isaac_Joy_Identity_Role]') AND OBJECTPROPERTY(id, 'IsUserTable') = 1");
            sbSql.AppendLine(") DROP TABLE Isaac_Joy_Identity_Role");

            sbSql.AppendLine("CREATE TABLE Isaac_Joy_Identity_Role");
            sbSql.AppendLine("(");
            sbSql.AppendLine("Id int IDENTITY(1,1) NOT NULL,");
            sbSql.AppendLine("Name nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Value nvarchar(2000) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("IsDelete int NOT NULL DEFAULT(0)");
            sbSql.AppendLine(")");

            sbSql.AppendLine("ALTER TABLE Isaac_Joy_Identity_Role");
            sbSql.AppendLine("WITH NOCHECK ADD CONSTRAINT Pk_Isaac_Joy_Identity_Role PRIMARY KEY NONCLUSTERED ( [Id] )");

            sbSql.AppendLine("IF EXISTS (");
            sbSql.AppendLine("SELECT * FROM sysobjects");
            sbSql.AppendLine("WHERE id = OBJECT_ID('[Isaac_Joy_Identity_Permission]') AND OBJECTPROPERTY(id, 'IsUserTable') = 1");
            sbSql.AppendLine(") DROP TABLE Isaac_Joy_Identity_Permission");

            sbSql.AppendLine("CREATE TABLE Isaac_Joy_Identity_Permission");
            sbSql.AppendLine("(");
            sbSql.AppendLine("Id int IDENTITY(1,1) NOT NULL,");
            sbSql.AppendLine("PluginName nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Code nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Name nvarchar(200) NOT NULL DEFAULT(''),");
            sbSql.AppendLine("Description nvarchar(2000) NOT NULL DEFAULT('')");
            sbSql.AppendLine(")");

            sbSql.AppendLine("ALTER TABLE Isaac_Joy_Identity_Permission");
            sbSql.AppendLine("WITH NOCHECK ADD CONSTRAINT Pk_Isaac_Joy_Identity_Permission PRIMARY KEY NONCLUSTERED ( [Id] )");

            _instence.Execute(sbSql.ToString());

            sbSql.Clear();
            sbSql.AppendLine("INSERT INTO Isaac_Joy_Identity_Role");
            sbSql.AppendLine("(");
            sbSql.AppendLine("  Name");
            sbSql.AppendLine("  ,Value");
            sbSql.AppendLine(")");
            sbSql.AppendLine("VALUES");
            sbSql.AppendLine("(");
            sbSql.AppendLine("  '管理员'");
            sbSql.AppendLine("  ,'1'");
            sbSql.AppendLine(")");

            sbSql.AppendLine("INSERT INTO Isaac_Joy_Identity_User");
            sbSql.AppendLine("(");
            sbSql.AppendLine("  Account");
            sbSql.AppendLine("  ,Password");
            sbSql.AppendLine("  ,Email");
            sbSql.AppendLine("  ,NickName");
            sbSql.AppendLine("  ,Birthday");
            sbSql.AppendLine("  ,Mobile");
            sbSql.AppendLine("  ,Tel");
            sbSql.AppendLine("  ,QQ");
            sbSql.AppendLine("  ,Address");
            sbSql.AppendLine("  ,Gender");
            sbSql.AppendLine("  ,CreateTime");
            sbSql.AppendLine("  ,UpdateTime");
            sbSql.AppendLine("  ,IsDelete");
            sbSql.AppendLine("  ,Roleid");
            sbSql.AppendLine(")");
            sbSql.AppendLine("VALUES");
            sbSql.AppendLine("(");
            sbSql.AppendLine("  'admin'");
            sbSql.AppendLine("  ,'334A3D26A8A54CE1BA7E588E6108A8B9'");
            sbSql.AppendLine("  ,'isaac.joy.cn@hotmail.com'");
            sbSql.AppendLine("  ,'joy'");
            sbSql.AppendLine("  ,'1985-01-27 00:00:00.000'");
            sbSql.AppendLine("  ,'13569868233'");
            sbSql.AppendLine("  ,'13569868233'");
            sbSql.AppendLine("  ,'53590040'");
            sbSql.AppendLine("  ,'河南省新乡市'");
            sbSql.AppendLine("  ,1");
            sbSql.AppendLine("  ,'" + DateTime.Now.ToString("yyyy-MM-dd") + "'");
            sbSql.AppendLine("  ,'" + DateTime.Now.ToString("yyyy-MM-dd") + "'");
            sbSql.AppendLine("  ,0");
            sbSql.AppendLine("  ,1");
            sbSql.AppendLine(");");

            _instence.Execute(sbSql.ToString());
        }

        public static void CreatePermission()
        {
            var sbSql = new StringBuilder();

            var extensions = Activator.BundleContext.GetExtensions("Isaac.Joy.Identity.PermissionConfigCreater");
            foreach (var extension in extensions)
            {
                foreach (var item in extension.Data)
                {
                    var creater = XmlSerializable.Deserialize<PermissionConfigCreater>(item);
                    var config = System.Activator.CreateInstance(extension.Owner.LoadClass(creater.Type)) as IPermissionsConfig;
                    if (config != null)
                    {
                        foreach (var permission in config.Permissions)
                        {
                            sbSql.AppendLine("IF NOT EXISTS");
                            sbSql.AppendLine("(");
                            sbSql.AppendLine("  SELECT");
                            sbSql.AppendLine("  *");
                            sbSql.AppendLine("  FROM Isaac_Joy_Identity_Permission");
                            sbSql.AppendLine("  WHERE PluginName = '" + extension.Owner.Name + "'");
                            sbSql.AppendLine("  AND Code = '" + permission.Code + "'");
                            sbSql.AppendLine(")");
                            sbSql.AppendLine("INSERT INTO Isaac_Joy_Identity_Permission");
                            sbSql.AppendLine("(");
                            sbSql.AppendLine("  PluginName");
                            sbSql.AppendLine("  ,Code");
                            sbSql.AppendLine("  ,Name");
                            sbSql.AppendLine("  ,Description");
                            sbSql.AppendLine(")");
                            sbSql.AppendLine("VALUES");
                            sbSql.AppendLine("(");
                            sbSql.AppendLine("  '" + extension.Owner.Name + "'");
                            sbSql.AppendLine("  ,'" + permission.Code + "'");
                            sbSql.AppendLine("  ,'" + permission.Name + "'");
                            sbSql.AppendLine("  ,'" + permission.Description + "'");
                            sbSql.AppendLine(")");
                        }
                    }
                }
            }
            _instence.Execute(sbSql.ToString());

            sbSql.Clear();
            sbSql.AppendLine("SELECT Max(Id) FROM Isaac_Joy_Identity_Permission");
            var maxid = _instence.ExecuteScalar<int>(sbSql.ToString());

            var fvalue = FlagsValue.CreateAll(maxid);
            sbSql.Clear();
            sbSql.AppendLine("UPDATE Isaac_Joy_Identity_Role SET Value = '" + fvalue + "' WHERE Id = 1");
            _instence.Execute(sbSql.ToString());
        }


        public static void ResetPermission()
        {
            var sbSql = new StringBuilder();

            var extensions = Activator.BundleContext.GetExtensions("Isaac.Joy.Identity.PermissionConfigCreater");
            foreach (var extension in extensions)
            {
                foreach (var item in extension.Data)
                {
                    var creater = XmlSerializable.Deserialize<PermissionConfigCreater>(item);
                    var config = System.Activator.CreateInstance(extension.Owner.LoadClass(creater.Type)) as IPermissionsConfig;
                    if (config != null)
                    {
                        sbSql.AppendLine("TRUNCATE TABLE Isaac_Joy_Identity_Permission;");
                        foreach (var permission in config.Permissions)
                        {
                            sbSql.AppendLine("INSERT INTO Isaac_Joy_Identity_Permission");
                            sbSql.AppendLine("(");
                            sbSql.AppendLine("  PluginName");
                            sbSql.AppendLine("  ,Code");
                            sbSql.AppendLine("  ,Name");
                            sbSql.AppendLine("  ,Description");
                            sbSql.AppendLine(")");
                            sbSql.AppendLine("VALUES");
                            sbSql.AppendLine("(");
                            sbSql.AppendLine("  '" + extension.Owner.Name + "'");
                            sbSql.AppendLine("  ,'" + permission.Code + "'");
                            sbSql.AppendLine("  ,'" + permission.Name + "'");
                            sbSql.AppendLine("  ,'" + permission.Description + "'");
                            sbSql.AppendLine(")");
                        }
                    }
                }
            }
            _instence.Execute(sbSql.ToString());

            sbSql.Clear();
            sbSql.AppendLine("SELECT Max(Id) FROM Isaac_Joy_Identity_Permission");
            var maxid = _instence.ExecuteScalar<int>(sbSql.ToString());

            var fvalue = FlagsValue.CreateAll(maxid);
            sbSql.Clear();
            sbSql.AppendLine("UPDATE Isaac_Joy_Identity_Role SET Value = '" + fvalue + "' WHERE Id = 1;");
            sbSql.AppendLine("UPDATE Isaac_Joy_Identity_Role SET Value = '' WHERE Id <> 1;");
            _instence.Execute(sbSql.ToString());
        }
    }
}
